Typical HAL USART use cases for migration

This section provides information about typical HAL USART use cases for migration.

Note

The processes for transmitting and receiving data using polling, interrupt or DMA are the same in HAL1 and HAL2, except for the specification of buffer size: HAL1 uses Size for the number of data elements (u8 or u16), while HAL2 uses Size_byte for the buffer size in bytes.

Use case: USART communication in polling mode

Sequence diagram

USART processing in polling mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2

== USART Processing in polling mode ==
alt polling
p1->p2: HAL_USART_Transmit(&husart,\n                                aTxBuffer,\n                                DATA_TO_SEND_SIZE,\n                                100)
note over p2 #00FF00
Transmitting data ongoing
end note

p2-->p1: <color #Green> HAL_OK
else
p1->p2: HAL_USART_Receive(&husart,\n                                aRxBuffer,\n                                DATA_TO_RECEIVE_SIZE,\n                                100)
note over p2 #00FF00
Receiving data ongoing
end note
p2-->p1: <color #Green> HAL_OK

else
p1->p2: HAL_USART_TransmitReceive(&husart,\n                                            aTxBuffer,\n                                            aRxBuffer,\n                                            DATA_TO_SEND_SIZE,\n                                            100)
note over p2 #00FF00
Transmitting and Receiving data ongoing
end note
p2-->p1: <color #Green> HAL_OK
end
@enduml

Code snippet

HAL1

HAL2

 #define DATA_TO_SEND_SIZE           256

 #define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE


 uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";


 uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

 USART_HandleTypeDef husart;


 HAL_USART_Init(&husart);




 HAL_USART_Receive(&husart, aRxBuffer,
                        DATA_TO_RECEIVE_SIZE, 100)

HAL_USART_Transmit(&husart, aTxBuffer,
                          DATA_TO_SEND_SIZE, 100)

HAL_USART_TransmitReceive(&husart, aTxBuffer,
                           aRxBuffer, DATA_TO_SEND_SIZE, 100)
#define DATA_TO_SEND_SIZE           256

#define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE


uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";


uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

hal_usart_handle_t husart;
hal_usart_config_t my_config;

HAL_USART_Init(&husart, HAL_USART1)

/* add config for usart instance */
HAL_USART_SetConfig(&husart, &my_config)

HAL_USART_Receive(&husart, aRxBuffer,
                        DATA_TO_RECEIVE_SIZE, 100)

HAL_USART_Transmit(&husart, aTxBuffer,
                        DATA_TO_SEND_SIZE, 100)


HAL_USART_TransmitReceive(&husart, aTxBuffer,
                          aRxBuffer, DATA_TO_SEND_SIZE, 100)

Key changes

  1. In HAL2, the USART instance is provided to HAL_USART_Init() and configuration is separated using HAL_USART_SetConfig().

Use case: USART RX in interrupt mode

Sequence diagram

USART receive in interrupt mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "USARTX_IRQHandler" as p3
== USART HAL Receive IT ==

p1->p2: <color: green> HAL_USART_Receive_IT(&husart, aRxBuffer, DATA_TO_RECEIVE_SIZE)
note over p2 #00FF00
Receiving data ongoing
end note
p2-->p1: HAL_OK
p3<-: USARTX data interrupt
p3->p2: HAL_USART_IRQHandler
note over p2 #FFFF99
All data (Size == husart->RxXferCount) have been received
end note
note over p2 #00FF00
End of receiving data
end note
p2->p1: HAL_USART_RxCpltCallback(&husart->RxXferCount)

@enduml

Code snippet

HAL1

HAL2

#define DATA_TO_RECEIVE_SIZE       256

uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

USART_HandleTypeDef husart;

/* Ensure that all required peripherals
(USART, GPIO, NVIC, etc.) are configured properly
/*
  ...
*/

/* USART register Receive complete user callback */
HAL_USART_RegisterCallback(&husart, HAL_USART_RX_CB_ID,
                               USART_RxCpltCallback);

/* Start a USART Process in interruption mode */
HAL_USART_Receive_IT(&husart, aRxBuffer,
                           DATA_TO_RECEIVE_SIZE)
#define DATA_TO_RECEIVE_SIZE       256

uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

hal_usart_handle_t husart;

/* Ensure that all required peripherals
(USART, GPIO,NVIC,etc.) are configured properly
/*
...
*/

/* USART register Receive complete user callback */
HAL_USART_RegisterRxCpltCallback(&husart, USART_RxCpltCallback);


/* Start a USART Process in interruption mode */
HAL_USART_Receive_IT(&husart, aRxBuffer,
                        DATA_TO_RECEIVE_SIZE)

Key changes

  1. HAL2 provides a dedicated registration API for RX completion callbacks: HAL_USART_RegisterRxCpltCallback().

  2. HAL2 uses byte-oriented transfer count fields (for example rx_xfer_count).


Use case: USART TX in interrupt mode

Sequence diagram

USART transmit in interrupt mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "USARTX_IRQHandler" as p3
== USART HAL Transmit IT ==

p1->p2: <color: green> HAL_USART_Transmit_IT(&husart, aTxBuffer, DATA_TO_SEND_SIZE)
note over p2 #00FF00
Transmitting data ongoing
end note
p2-->p1: HAL_OK
p3<-: USARTX data interrupt
p3->p2: HAL_USART_IRQHandler
note over p2 #FFFF99
All data (Size == husart->TxXferCount) have been transmitted
end note
note over p2 #00FF00
End of transmitting data
end note
p2->p1: HAL_USART_TxCpltCallback(&husart->TxXferCount)

@enduml

Code snippet

HAL1

HAL2

#define DATA_TO_SEND_SIZE           256

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";

USART_HandleTypeDef husart;

/* Ensure that all required peripherals
(USART, GPIO, NVIC,etc.) are configured properly
/*
...
*/

/* USART register Transmit complete user callback */
HAL_USART_RegisterCallback(&husart, HAL_USART_TX_CB_ID,
                               USART_TxCpltCallback);

/* Start a USART Process in interruption mode */
HAL_USART_Transmit_IT(&husart, aTxBuffer,
                              DATA_TO_SEND_SIZE)
#define DATA_TO_SEND_SIZE           256

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";

hal_usart_handle_t husart;

/* Ensure that all required peripherals
(USART, GPIO, NVIC,etc.) are configured properly
/*
...
*/

/* USART register Transmit complete user callback */
HAL_USART_RegisterTxCpltCallback(&husart, USART_TxCpltCallback);


/* Start a USART Process in interruption mode */
HAL_USART_Transmit_IT(&husart, aTxBuffer,
                              DATA_TO_SEND_SIZE)

Key changes

  1. HAL2 provides a dedicated registration API for TX completion callbacks: HAL_USART_RegisterTxCpltCallback().

  2. HAL2 uses byte-oriented transfer count fields (for example tx_xfer_count).


Use case: USART TX RX in interrupt mode

Sequence diagram

USART transmit and receive in interrupt mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "USARTX_IRQHandler" as p3
== USART HAL TransmitReceive IT ==

p1->p2: <color: green> HAL_USART_TransmitReceive_IT(&husart, aTxBuffer, aRxBuffer, DATA_TO_SEND_SIZE)
note over p2 #00FF00
Transmitting and receiving data ongoing
end note
p2-->p1: HAL_OK
p3<-: USARTX data interrupt
p3->p2: HAL_USART_IRQHandler
note over p2 #FFFF99
All data (Size == husart->TxXferCount and Size == husart->RxXferCount) have been transmitted and received
end note
note over p2 #00FF00
End of transmitting and receiving data
end note
p2->p1: HAL_USART_TxRxCpltCallback(&husart->TxXferCount, husart->RxXferCount)

@enduml

Code snippet

HAL1

HAL2

#define DATA_TO_SEND_SIZE           256

#define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";
uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

USART_HandleTypeDef husart;

/* Ensure that all required peripherals
(USART, GPIO, NVIC,etc.) are configured properly
/*
...
*/

/* USART register TransmitReceive complete user callback */
HAL_USART_RegisterCallback(&husart, HAL_USART_TX_RX_CB_ID, USART_TxRxCpltCallback);

/* Start a USART TransmitReceive process in interruption mode */
HAL_USART_TransmitReceive_IT(&husart, aTxBuffer, aRxBuffer, DATA_TO_SEND_SIZE)
#define DATA_TO_SEND_SIZE           256

#define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";
uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

hal_usart_handle_t husart;

/* Ensure that all required peripherals
(USART, GPIO, NVIC,etc.) are configured properly
/*
...
*/

/* USART register TransmitReceive complete user callback */
HAL_USART_RegisterTxRxCpltCallback(&husart, USART_TxRxCpltCallback);

/* Start a USART TransmitReceive process in interruption mode */
HAL_USART_TransmitReceive_IT(&husart, aTxBuffer, aRxBuffer, DATA_TO_RECEIVE_SIZE)

Key changes

  1. HAL2 provides a dedicated registration API for TX/RX completion callbacks: HAL_USART_RegisterTxRxCpltCallback().

  2. HAL2 uses byte-oriented transfer count fields (for example tx_xfer_count and rx_xfer_count).

Related examples in HAL2

Example name

Brief

hal_usart_two_boards_com_it_controller

How to handle an infinite number of transmit-receive transactions between two boards based on the USART-bus protocol with the HAL API, in interrupt mode.

hal_usart_two_boards_com_it_responder

How to respond in an interrupt mode USART communication, driven by the controller, using the HAL API.


Use case: USART RX in DMA mode

Sequence diagram

USART receive in DMA mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "DMA" as p3
participant "DMAx_IRQHandler" as p4

== USART HAL Receive DMA ==
p1->p2: <color: green> HAL_USART_Receive_DMA(&husart, aRxBuffer, DATA_TO_RECEIVE_SIZE)
note over p2 #00FF00
Receiving data ongoing
end note
p2->p3: HAL_DMA_Start_IT()
p3-->p2: HAL_OK
p2-->p1: HAL_OK

p4<-: DMAx complete interrupt
p4->p3: HAL_DMA_IRQHandler
note over p3 #00FF00
End of receiving data
end note
p3->p2: XferCpltCallback
p2->p1: HAL_USART_RxCpltCallback(&husart->rx_xfer_count)
@enduml

Code snippet

HAL1

HAL2

#define DATA_TO_RECEIVE_SIZE  255

uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

USART_HandleTypeDef husart;

/* Ensure that all required peripherals
(USART, GPIO, DMA, NVIC,etc.) are configured properly
/*
...
*/

/* USART register Receive complete user callback */
HAL_USART_RegisterCallback(&husart, HAL_USART_RX_CB_ID,
                              USART_RxCpltCallback);

/* Start a USART Process in DMA mode */
HAL_USART_Receive_DMA(&husart, aRxBuffer,
                        DATA_TO_RECEIVE_SIZE)
#define DATA_TO_RECEIVE_SIZE  255

uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

hal_usart_handle_t husart;

/* Ensure that all required peripherals
(USART, GPIO, DMA, NVIC,etc.) are configured properly
/*
 ...
*/

/* USART register Receive complete user callback */
HAL_USART_RegisterRxCpltCallback(&husart, USART_RxCpltCallback);


/* Start a USART Process in DMA mode */
HAL_USART_Receive_DMA(&husart, aRxBuffer,
                             DATA_TO_RECEIVE_SIZE)

Key changes

  1. HAL2 DMA start uses HAL_DMA_StartPeriphXfer_IT_Opt() (optional interrupt generation) instead of HAL_DMA_Start_IT().

  2. HAL2 provides a dedicated registration API for RX completion callbacks: HAL_USART_RegisterRxCpltCallback().


Use case: USART TX in DMA mode

Sequence diagram

USART transmit in DMA mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "USARTX_IRQHandler" as p5
participant "DMA" as p3
participant "DMAx_IRQHandler" as p4

== USART HAL Transmit DMA ==
p1->p2: <color: green> HAL_USART_Transmit_DMA(&husart, aTxBuffer, DATA_TO_SEND_SIZE)
note over p2 #00FF00
Transmitting data ongoing
end note
p2->p3: HAL_DMA_Start_IT()
p3-->p2: HAL_OK
p2-->p1: HAL_OK

p4<-: DMAx complete interrupt
p4->p3: HAL_DMA_IRQHandler
note over p3 #00FF00
End of transmitting data
end note
p3->p2: XferCpltCallback
p2->p2: Enable USARTx Transmit Complete IRQ (TCIE)
p5<-: USARTx Transmit Complete (TCIE)
p5->p2: HAL_USART_IRQHandler
p2->p1: HAL_USART_TxCpltCallback(&husart->TxXferCount)
@enduml

Code snippet

HAL1

HAL2

 #define DATA_TO_SEND_SIZE  255

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";

 USART_HandleTypeDef husart;

 /* Ensure that all required peripherals
 (USART, GPIO, DMA, NVIC,etc.) are configured properly
 /*
 ...
 */

 /* USART register Transmit complete user callback */
 HAL_USART_RegisterCallback(&husart, HAL_USART_TX_CB_ID,
                               USART_TxCpltCallback);

 /* Start a USART Process in dma mode */
 HAL_USART_Transmit_DMA(&husart, aTxBuffer,
                               DATA_TO_SEND_SIZE)
 #define DATA_TO_SEND_SIZE  255

uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";

 hal_usart_handle_t husart;

 /* init and config for USART instance */
 /*
 ...
 */

 /* USART register Transmit complete user callback */
 HAL_USART_RegisterTxCpltCallback(&husart, USART_TxCpltCallback);



 /* Start a USART Process in dma mode */
 HAL_USART_Transmit_DMA(&husart, aTxBuffer,
                               DATA_TO_SEND_SIZE)

Key changes

  1. HAL2 DMA start uses HAL_DMA_StartPeriphXfer_IT_Opt() (optional interrupt generation) instead of HAL_DMA_Start_IT().

  2. HAL2 provides a dedicated registration API for TX completion callbacks: HAL_USART_RegisterTxCpltCallback().


Use case: USART TX RX in DMA mode

Sequence diagram

USART transmit and receive in DMA mode

@startuml
participant "User Application" as p1
participant "HAL USART driver" as p2
participant "DMA" as p3
participant "DMAx_IRQHandler" as p4

== USART HAL TransmitReceive DMA ==
p1->p2: <color: green> HAL_USART_TransmitReceive_DMA(&husart, aTxBuffer, aRxBuffer, DATA_TO_SEND_SIZE)
note over p2 #00FF00
Transmitting and receiving data ongoing
end note
p2->p3: HAL_DMA_Start_IT()
p3-->p2: HAL_OK
p2-->p1: HAL_OK

p4<-: DMAx complete interrupt
p4->p3: HAL_DMA_IRQHandler
note over p3 #00FF00
End of transmitting and receiving data
end note
p3->p2: XferCpltCallback
p2->p1: HAL_USART_TxRxCpltCallback(&husart->TxXferCount, husart->RxXferCount)
@enduml

Code snippet

HAL1

HAL2

#define DATA_TO_SEND_SIZE           256

#define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE


uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";


uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

USART_HandleTypeDef husart;

/* Ensure that all required peripherals
(USART, GPIO, DMA, NVIC,etc.) are configured properly
/*
...
*/

/* USART register TransmitReceive complete user callback */
HAL_USART_RegisterCallback(&husart, HAL_USART_TX_RX_CB_ID, USART_TxRxCpltCallback);

/* Start a USART TransmitReceive process in dma mode */
HAL_USART_TransmitReceive_DMA(&husart, aTxBuffer,
                                      aRxBuffer, DATA_SIZE)
#define DATA_TO_SEND_SIZE           256

#define DATA_TO_RECEIVE_SIZE       DATA_TO_SEND_SIZE


uint8_t aTxBuffer[] = " **** USART_SlaveMode **** ";


uint8_t aRxBuffer[DATA_TO_RECEIVE_SIZE];

hal_usart_handle_t usart_handle;

/* Ensure that all required peripherals
(USART, GPIO, DMA, NVIC,etc.) are configured properly
/*
...
*/

/* USART register TransmitReceive complete user callback */
HAL_USART_RegisterTxRxCpltCallback(&usart_handle, USART_TxRxCpltCallback);

/* Start a USART TransmitReceive process in dma mode */
HAL_USART_TransmitReceive_DMA(&usart_handle, aTxBuffer,
                                     aRxBuffer, DATA_TO_SEND_SIZE)

Key changes

  1. HAL2 DMA start uses HAL_DMA_StartPeriphXfer_IT_Opt() (optional interrupt generation) instead of HAL_DMA_Start_IT().

  2. HAL2 provides a dedicated registration API for TX/RX completion callbacks: HAL_USART_RegisterTxRxCpltCallback().

Related examples in HAL2

Example name

Brief

hal_usart_two_boards_com_dma_controller

How to handle an infinite number of transmit-receive transactions between two boards based on the USART-bus protocol with the HAL API, in DMA mode.

hal_usart_two_boards_com_dma_responder

How to respond in a dma mode USART communication, driven by the controller, using the HAL API.